﻿using WeighClient.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
using System.Drawing;
using ZXing;
using ZXing.Common;
using ZXing.QrCode.Internal;
using System.IO;
using System.Security.Cryptography;
using OfficeOpenXml;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Threading;

namespace WeighClient.Utils
{
    public  class PrintUtils
    {
        SynchronizationContext _syncContext = SynchronizationContext.Current;
        static string status = "";
        static string fileName = "";

        public static void printWeighOrder(Bill billModel)
        {
            findBillLog(billModel.orderCode);

            if ("1".Equals(status))
            {
                fileName = "tplWeighOrderzg";
            }
            else if ("2".Equals(status))
            {
                fileName = "tplWeighOrderqs";

            }
            else if ("3".Equals(status))
            {
                fileName = "tplWeighOrder";

            }
            else
            {
                fileName = "tplWeighOrder";

            }
            string jmCode = md5(billModel.id);
            doUpdateScreenPicture(billModel.id, billModel.id);
            Bitmap bitmap = Create(billModel.id);
            insertPic();
            
            doPrint(fileName, billModel);
             status = "";
             fileName = "";

        }

        private static void doPrint(string tplName,Bill billModel)
        {
            Excel.Application ExcelApp = new Excel.Application();
            ExcelApp.Visible = false;//是打开可见
            Excel.Workbooks wbks = ExcelApp.Workbooks;
            Excel._Workbook wbk = wbks.Add(System.AppDomain.CurrentDomain.BaseDirectory + "/Reports/"+ tplName + ".xlsx");
            Excel.Worksheet ws = (Excel.Worksheet)wbk.Worksheets[1];

            billModel.CurTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            try
            {
                int rows = ws.UsedRange.Rows.Count;
                int columns = ws.UsedRange.Columns.Count;

                for (int i = 1; i <= rows; i++)
                {
                    for (int j = 1; j <= columns; j++)
                    {
                        if (null != ws.Cells[i, j] && null != ws.Cells[i, j].Value2)
                        {
                            string _val = ws.Cells[i, j].Value2.ToString();
                            if (!_val.StartsWith("${"))
                            {
                                continue;
                            }
                            string fieldName = _val.Substring(2, _val.Length - 3);
                            try
                            {
                                FieldInfo filedInfo = billModel.GetType().GetField(fieldName);
                                if (null != filedInfo.GetValue(billModel))
                                {
                                    ws.Cells[i, j] = filedInfo.GetValue(billModel).ToString();
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            wbk.PrintOutEx();
            //Type.Missing, Type.Missing, Type.Missing, Type.Missing, "MS-D347", Type.Missing, Type.Missing, Type.Missing, Type.Missing
            //1, 2, 1,false, "POS80", true, true, tplName + ".xlsx", false
            //wbk.PrintOutEx(1, 1, 1, printerName, false, false, false, false);
            KillProcess(ExcelApp); //杀掉生成的进程
            GC.Collect(); //垃圾回收机制
        }
        [DllImport("User32.dll")]
        public static extern int GetWindowThreadProcessId(IntPtr Hwnd, out int PID);
        private static void KillProcess(Excel.Application AppObject)
        {
            int Pid = 0;
            IntPtr Hwnd = new IntPtr(AppObject.Hwnd);
            System.Diagnostics.Process p = null;
            try
            {
                GetWindowThreadProcessId(Hwnd, out Pid);
                p = System.Diagnostics.Process.GetProcessById(Pid);
                if (p != null)
                {
                    p.Kill();
                    p.Dispose();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("进程关闭失败！异常信息：" + ex);
            }
        }
        public static Bitmap Create(string msg)
        {
            MultiFormatWriter writer = new MultiFormatWriter();
            Dictionary<EncodeHintType, object> hint = new Dictionary<EncodeHintType, object>();
            //设置二维码为utf-8编码
            hint.Add(EncodeHintType.CHARACTER_SET, "utf-8");
            //设置纠错等级， 高
            hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            BitMatrix bm = writer.encode(msg, BarcodeFormat.QR_CODE, 200, 120, hint);
            BarcodeWriter barcodeWriter = new BarcodeWriter();
            //{
            //    Format = BarcodeFormat.QR_CODE,
            //    Options = new ZXing.Common.EncodingOptions
            //    {
            //        Margin = 0, // 设置二维码边距为0，即去除白框
            //        Width = 300, // 设置二维码图片宽度
            //        Height = 300 // 设置二维码图片高度 }
            //    }
            //};
            Bitmap bitmap = barcodeWriter.Write(bm);
            string codePath = Directory.GetCurrentDirectory() + "/code.jpg";
            if (File.Exists(codePath))
                File.Delete(codePath);
            bitmap.Save(codePath);
            return bitmap;
        }





         public static string md5(string input)
        {
            // Use input string to calculate MD5 hash
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
                // To force the hex string to lower-case letters instead of
                // upper-case, use he following line instead:
                // sb.Append(hashBytes[i].ToString("x2")); 
            }
            return sb.ToString();
        }
        public static void insertPic()
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            ExcelPackage excel = new ExcelPackage(new FileInfo(System.AppDomain.CurrentDomain.BaseDirectory + "/Report/" + fileName+".xlsx"));
            var ws = excel.Workbook.Worksheets[0];
            FileInfo imageFile = new FileInfo(System.AppDomain.CurrentDomain.BaseDirectory + "/code.jpg");
            var picture = ws.Drawings.AddPicture(DateTime.Now.ToString("yyyyMMddHHmmss"), imageFile);
            if ("tplWeighOrderqs".Equals(fileName))//回磅打印tplWeighOrder
            {
                picture.SetPosition(130, 105);
                picture.SetSize(130, 85);
            }
            else
            {
                picture.SetPosition(125, 105);
                picture.SetSize(130, 85);
            }
            
            //picture.SetPosition(430, 50);
            //picture.SetSize(180, 120);
            excel.SaveAs(new FileInfo(System.AppDomain.CurrentDomain.BaseDirectory + "/Reports/"+ fileName+".xlsx"));
        }
        public static void doUpdateScreenPicture(String encryptionNumber, String id)
        {
            JObject paramObject = new JObject();
            paramObject.Add("encryptionNumber", encryptionNumber);
            paramObject.Add("id", id);

            try
            {
                String serverIp = App.GetConfig().HttpServerIp;
                String serverPort = App.GetConfig().HttpServerPort;
                String response = HttpPostHelper.doHttpPost("http://" + serverIp + ":" + serverPort + "/qd-s-purchase/purchaseBill/updateBillWeightPicture", paramObject.ToString());
                JObject rspJson = JObject.Parse(response);
                string code = rspJson["code"].ToString();
                if (code.ToLower() == "00000")
                {
                }
            }
            catch (Exception ex) { }
        }

        public static void findBillLog(String billNo)
        {
            JObject paramObject = new JObject();
            paramObject.Add("billNo", billNo);
            List<string> statusList = new List<string>();
            List<string> coldStatusList = new List<string>();
            try
            {
                String serverIp = App.GetConfig().HttpServerIp;
                String serverPort = App.GetConfig().HttpServerPort;
                String response = HttpPostHelper.doHttpPost("http://" + serverIp + ":" + serverPort + "/qd-s-factory/clientApi/findBillLogList", paramObject.ToString());
                JObject rspJson = JObject.Parse(response);
                string code = rspJson["code"].ToString();
                {
                    var jsonStr = rspJson["data"].ToString();
                    List<BillLog> bills = JsonConvert.DeserializeObject<List<BillLog>>(jsonStr);

                    foreach (BillLog billLog in bills)
                    {
                        statusList.Add(billLog.status);
                        coldStatusList.Add(billLog.coldStatus);
                    }
                    if (statusList.Contains("41"))
                    {
                        status = "1";
                    }
                    else if (statusList.Contains("511"))
                    {
                        status = "2";
                    }
                    else if (coldStatusList.Contains("3"))
                    {
                        status = "3";
                    }else if (coldStatusList.Contains("2"))
                    {
                        status="4";
                    }else if (coldStatusList.Contains("2")&&statusList.Contains("511"))
                    {
                        status = "5";
                    }
                    else
                    {
                        status = "6";
                    }
                }
            }
            catch (Exception ex) { }
        }

        //private void SetDataList(object obj)
        //{
        //    List<string> statusList = new List<string>();
        //    if (null == obj) return;
        //    List<BillLog> bills = (List<BillLog>)obj;
        //    foreach (BillLog billLog in bills)
        //    {
        //        statusList.Add(billLog.status);
        //    }
        //    if (statusList.Contains("41"))
        //    {
        //        status = "1";
        //    }else if (statusList.Contains("511"))
        //    {
        //        status = "2";
        //    }else if (statusList.Contains("521"))
        //    {
        //        status = "3";
        //    }
        //}
    }
}
